﻿using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WCAD
{
    public static class PmPolylineMethod
    {
        public static List<Curve> ExplodePolyline(Polyline polyline)
        {
            DBObjectCollection dbs = new DBObjectCollection();
            polyline.Explode(dbs);
            List<Curve> curves = new List<Curve>();
            foreach (Curve item in dbs)
            {
                curves.Add(item);
            }
            return curves;
        }
        public static Polyline CreatePolylineByExtents3d(Extents3d extents)
        {
            Polyline pl = new Polyline();
            pl.AddVertexAt(0, new Point2d(extents.MinPoint.X, extents.MinPoint.Y), 0, 0, 0);
            pl.AddVertexAt(1, new Point2d(extents.MaxPoint.X, extents.MinPoint.Y), 0, 0, 0);
            pl.AddVertexAt(2, new Point2d(extents.MaxPoint.X, extents.MaxPoint.Y), 0, 0, 0);
            pl.AddVertexAt(3, new Point2d(extents.MinPoint.X, extents.MaxPoint.Y), 0, 0, 0);
            pl.Closed = true;
            return pl;
        }
        public static Polyline CreatePolyline(List<Point3d> points,bool isClosed=true)
        {
            Polyline pl = new Polyline();
            for (int i = 0; i < points.Count; i++)
            {
                pl.AddVertexAt(i, points[i].Convert2d(new Plane()), 0, 0, 0);
            }
            pl.Closed = isClosed;
            return pl;
        }
        public static List<Point2d> GetPoint2ds(this Polyline polyline)
        {
            List<Point2d> points = new List<Point2d>();
            for (int i = 0; i < polyline.NumberOfVertices; i++)
            {
                points.Add(polyline.GetPoint2dAt(i));
            }
            return points;
        }
        public static List<Point3d> GetPoint3ds(this Polyline polyline)
        {
            List<Point3d> points = new List<Point3d>();
            for (int i = 0; i < polyline.NumberOfVertices; i++)
            {
                points.Add(polyline.GetPoint3dAt(i));
            }
            return points;
        }
        /// <summary>
        /// 延长多段线其中一段（只适用于全直线的多段线）
        /// </summary>
        /// <param name="polyline"></param>
        /// <param name="num">节点索引</param>
        /// <param name="dis">延长长度</param>
        public static void ExtendPolyline(Polyline polyline, int num, double dis)
        {
            List<Point2d> points = polyline.GetPoint2ds();
            if (num > points.Count - 1) return;
            CompositeCurve3d curve3D = polyline.GetGeCurve() as CompositeCurve3d;
            Curve3d curve = curve3D.GetCurves()[num == 0 ? 1 : num - 1];
            if (curve is CircularArc3d arc && num > 0)
            {
                Point3d center = arc.Center;
                double radius = arc.Radius;
                double ro = dis / radius;
                if (arc.Normal.Z < 0) ro = Math.PI * 2 - ro;
                for (int i = num; i < points.Count; i++)
                {
                    if (i == 0) continue;
                    points[i] = points[i].RotateBy(ro, center.Convert2d(new Plane()));
                }
                Vector3d vector1 = center.GetVectorTo(points[num - 1].ToPoint3d());
                Vector3d vector2 = center.GetVectorTo(points[num].ToPoint3d());
                double bu = Math.Tan(vector1.GetAngleTo(vector2, arc.Normal) / 4);
                if (arc.Normal.Z < 0) bu *= -1;
                polyline.SetBulgeAt(num - 1, bu);
            }
            else
            {
                Point3d point3d = polyline.GetPointAtParameter(num - (num > 0 ? 0.1 : 0));
                Vector2d vector = polyline.GetFirstDerivative(point3d).Convert2d(new Plane());
                vector = vector.GetNormal() * dis;
                for (int i = num; i < points.Count; i++)
                {
                    if (i == 0) continue;
                    points[i] += vector;
                }
            }

            for (int i = 0; i < points.Count; i++)
            {
                if (i == 0) continue;
                polyline.SetPointAt(i, points[i]);
            }

        }
    }
}
